﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

namespace MetaDrive.Core
{
    public static class DTEHelper
    {
        const uint S_OK = 0;

        [DllImport("ole32.dll")]
        public static extern uint GetRunningObjectTable(uint reserved, out IRunningObjectTable ROT);

        [DllImport("ole32.dll")]
        public static extern uint CreateBindCtx(uint reserved, out IBindCtx ctx);

        static IDictionary<string, object> GetRunningObjectTable()
        {
            IDictionary<string, object> rotTable = new Dictionary<string, object>();

            IRunningObjectTable runningObjectTable;
            IEnumMoniker monikerEnumerator;
            IMoniker[] monikers = new IMoniker[1];

            GetRunningObjectTable(0, out runningObjectTable);
            runningObjectTable.EnumRunning(out monikerEnumerator);
            monikerEnumerator.Reset();

            IntPtr numberFetched = IntPtr.Zero;

            while (monikerEnumerator.Next(1, monikers, numberFetched) == 0)
            {
                IBindCtx ctx;
                CreateBindCtx(0, out ctx);

                string runningObjectName;
                monikers[0].GetDisplayName(ctx, null, out runningObjectName);
                Marshal.ReleaseComObject(ctx);

                object runningObjectValue;
                runningObjectTable.GetObject(monikers[0], out runningObjectValue);

                if (!rotTable.ContainsKey(runningObjectName))
                    rotTable.Add(runningObjectName, runningObjectValue);
            }

            return rotTable;
        }

        public static IDictionary<string, EnvDTE80.DTE2> GetRunningVSIDETable()
        {
            IDictionary<string, object> runningObjects = GetRunningObjectTable();
            IDictionary<string, EnvDTE80.DTE2> runningDTEObjects = new Dictionary<string, EnvDTE80.DTE2>();

            foreach (string objectName in runningObjects.Keys)
            {
                if (!objectName.StartsWith("!VisualStudio.DTE"))
                    continue;

                EnvDTE80.DTE2 ide = runningObjects[objectName] as EnvDTE80.DTE2;
                if (ide == null)
                    continue;

                runningDTEObjects.Add(objectName, ide);
            }

            return runningDTEObjects;
        }
    }
}
